#ifndef RENDERSYSTEM_H
#define RENDERSYSTEM_H

//#include <GL/gl.h>
#include "StompedReality/Core.h"
#include "StompedReality/Core/GameAccess.h"
#include "StompedReality/Core/Graphics/GLExtensions.h"
#include "StompedReality/Core/Graphics/RenderGroup.h"
#include "StompedReality/Core/MessageSystem/Message.h"
namespace StompedReality
{
namespace Graphics
{

class RenderFunction;

typedef RenderGroup* RenderAtomArray;
struct Color
{
  float r;
  float g;
  float b;
  float a;
};

/*!
 *
 * \author	Stefan Kazalski
 *
 * \brief	Render system
 *
 *    Creates the render context and renders.
 */
class DLL_EXPORT RenderSystem : public StompedReality::GameAccess
{
 protected:

  int m_MaxRenderUnits;
  int m_RenderUnitEnqueue;

  RenderGroup* m_RenderGroups;
  Color m_ClearColorData;
  unsigned m_ClearMask;

  int m_Width;
  int m_Height;

 public:

  //! Constructor.
  RenderSystem( );

  //! Destructor.
  virtual ~RenderSystem( );

 public:

  /*!
   * \brief		Parses the render systems properties.
   *
   * \param		root	The json root.
   *
   * \return	True if success otherwise false.
   */
  virtual bool ParseConfig ( JsonPTR root );

  /*!
   * \brief		Creates a new windows.
   *
   * \param		width	The width of the render context.
   * \param		height	The height of the render context
   * \param		fullscreen	Is fullscreen.
   * \param		title	The windows title.
   *
   * \return	True if success otherwise false.
   */
  virtual bool InitWindow ( int width, int height, bool fullscreen, const char* title );

  /*!
   * \brief		Closes the window.
   *
   * \return	True if success otherwise false.
   */
  virtual bool CloseWindow( );

  /*!
   * \brief		Tests if the window is open.
   *
   * \return	True if open otherwise false.
   */
  virtual bool IsWindowOpen( );

  /*!
   * \brief		Initializes the OpneGL extensions.
   *
   * \return	True if success otherwise false
   */
  virtual bool InitGLExtensions( );

  /*!
   * \brief		Initializes the basic OpenGL renderer pipeline
   *
   *    Sets view model, deph test and blend mode.
   */
  void InitRenderState( );

  /*!
   * \brief		Sets the background color.
   *
   * \param  r	Red.
   * \param		g	Green.
   * \param		b	Blue.
   * \param		a	Alpha.
   */
  void SetBackgroundColor ( float r, float g, float b, float a );

  /*!
   * \brief		Resizes the render context and window.
   *
   *    Calls InitRenderState to update the render pipeline.
   *
   * \param		width	The width of the render context.
   * \param		height	The height of the render context
   */
  void Resize( int width, int height );

  //! \brief	Render conext width getter.
  int GetWidth( );

  //! \brief	Render conext height getter.
  int GetHeight( );

 public:

  /*!
   * \brief		Sets the render functions.
   *
   * \param		functions	The render functions.
   */

  //void SetRenderAtomFunctions( functions::RenderAtomFunctions* functions );

  /*!
   * \brief		Returns the current render functions.
   *
   * \return	The render functions.
   */

  //functions::RenderAtomFunctions* GetRenderAtomFunctions( );

  /*!
   * \brief		Starts the rendering of the frame.
   *
   *    Clears the render command queue.
   *    Adds clear buffer and clear color to the render commands of the current frame.
   *
   */
  void BeginRendering( );

  /*!
   * \brief		Ends the rendering of the frame.
   *
   *    Sorts the render command queue.
   *    Executes all commands.
   */
  void EndRendering( );

  /*!
   * \brief		Adds render groups to the queue.
   *
   * \param		group		The render group.
   */
  void QueueRenderGroup ( RenderGroup* group );

  /*!
   * \brief		Adds render command to the queue.
   *
   * \param		data		The commands data.
   * \param		function	The commands function.
   */

  //void AddRenderUnit ( RenderData* data, StompedReality::Graphics::functions::renderFunction function );

  /*!
   * \brief		Calculates a render key.
   *
   * \param		layer		The layer.
   * \param		objDepth	The objects depth.
   */
  unsigned int CalculateKey ( char layer, float objDepth );

  //! \brief	List of render commands.
  const RenderAtomArray GetRenderUnitList( );
  virtual void SwapBuffer ( );
  virtual void* GetDisplayPointer( ) {
    return 0;
  };
};

}
}
#endif // RENDERSYSTEM_H
